﻿ using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;

using Elegant.Ui;
using iPdf.Properties;
using PdfSharp.Drawing;

namespace iPdf
{
    abstract class WatermarkPage : ActionPage<ActionItem, WatermarkOption>
    {
        #region Properties

        public override string ActionName
        {
            get
            {
                return "Add" + base.ActionName;
            }
        }

        public override bool ReadyToAct
        {
            get
            {
                return base.ReadyToAct &&
                    this.layoutGroupEnabled &&
                    this.LayoutGallery.SelectedLayout != null &&
                    this.Preview.Pressed == false;
            }
        }

        public override bool SelectionSensitive
        {
            get
            {
                return true;
            }
        }


        public TataPosition WatermarkPosition
        {
            get
            {
                iPdf.TataPosition position;
                position.X = UnitConverter.InchToPoints(
                    (float)this.HorizontalPosition.Value );
                position.Y = UnitConverter.InchToPoints(
                    (float)this.VerticalPosition.Value );
                position.Rotation = (float)this.Rotation.Value;

                return position;
            }
        }

        public float WatermarkOpacity
        {
            get
            {
                return (float)this.OpacityLevel.Value / 100;
            }
        }

        protected bool LayoutSelected
        {
            get
            {
                return this.LayoutGallery.SelectedItem != null;
            }
        }

        protected TataLayout WatermarkLayout
        {
            get
            {
                GalleryItem hoveredItem = this.LayoutGallery.HoveredItem as GalleryItem;
                if (hoveredItem != null)
                {
                    return hoveredItem.Data as TataLayout;
                }

                return this.LayoutGallery.SelectedLayout;
            }
        }



        #endregion

        #region Ctor
        public WatermarkPage()
            : base()
        {
            visibleColumns.Add(Global.Grid.From);
            visibleColumns.Add(Global.Grid.To);
        }

        protected override void InitializeComponent()
        {
            this.LayoutGroup = new Elegant.Ui.RibbonGroup();
            this.HorizontalPosition = new Elegant.Ui.NumericUpDown();
            this.VerticalPosition = new Elegant.Ui.NumericUpDown();
            this.HorizontalPositionDescription = new Elegant.Ui.Label();
            this.VerticalPositionDescription = new Elegant.Ui.Label();
            this.Separator = new Elegant.Ui.Separator();
            this.Rotation = new Elegant.Ui.NumericUpDown();
            this.OpacityLevel = new Elegant.Ui.NumericUpDown();
            this.RotationDescription = new Elegant.Ui.Label();
            this.OpacityLevelDescription = new Elegant.Ui.Label();

            this.PreviewGroup = new Elegant.Ui.RibbonGroup();
            this.Preview = new Elegant.Ui.ToggleButton();

            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.LayoutGroup.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.HorizontalPosition)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.VerticalPosition)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Rotation)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.OpacityLevel)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.PreviewGroup)).BeginInit();
            this.PreviewGroup.SuspendLayout();
            this.SuspendLayout();

            // 
            // LayoutGroup
            // 
            this.LayoutGroup.BackColor = System.Drawing.SystemColors.Control;
            this.LayoutGroup.Controls.Add(this.HorizontalPosition);
            this.LayoutGroup.Controls.Add(this.VerticalPosition);
            this.LayoutGroup.Controls.Add(this.HorizontalPositionDescription);
            this.LayoutGroup.Controls.Add(this.VerticalPositionDescription);
            this.LayoutGroup.Controls.Add(this.Separator);
            this.LayoutGroup.Controls.Add(this.Rotation);
            this.LayoutGroup.Controls.Add(this.OpacityLevel);
            this.LayoutGroup.Controls.Add(this.RotationDescription);
            this.LayoutGroup.Controls.Add(this.OpacityLevelDescription);
            this.LayoutGroup.DialogLauncherButtonVisible = false;
            this.LayoutGroup.Id = Helper.GenerateGuid();
            this.LayoutGroup.LargeImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Layout)});
            this.LayoutGroup.Location = new System.Drawing.Point(222, 3);
            this.LayoutGroup.Name = "LayoutGroup";
            this.LayoutGroup.Size = new System.Drawing.Size(342, 94);
            this.LayoutGroup.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Layout16)});
            this.LayoutGroup.TabIndex = 1;
            this.LayoutGroup.Text = "Layout";
            // 
            // HorizontalPosition
            // 
            this.HorizontalPosition.DecimalPlaces = 1;
            this.HorizontalPosition.Id = Helper.GenerateGuid();
            this.HorizontalPosition.Increment = new decimal(new int[] {
            1,
            0,
            0,
            65536});
            this.HorizontalPosition.LabelText = "Horizontal";
            this.HorizontalPosition.Location = new System.Drawing.Point(25, 10);
            this.HorizontalPosition.Maximum = new decimal(new int[] {
            65536,
            0,
            0,
            0});
            this.HorizontalPosition.Minimum = new decimal(new int[] {
            65536,
            0,
            0,
            -2147483648});
            this.HorizontalPosition.Name = "HorizontalPosition";
            this.HorizontalPosition.Size = new System.Drawing.Size(106, 24);
            this.HorizontalPosition.TabIndex = 4;
            this.HorizontalPosition.TextEditorWidth = 25;
            this.LayoutGroup.SetVerticallyDistributed(this.HorizontalPosition, true);
            // 
            // VerticalPosition
            // 
            this.VerticalPosition.DecimalPlaces = 1;
            this.LayoutGroup.SetFlowBreak(this.VerticalPosition, true);
            this.VerticalPosition.Id = Helper.GenerateGuid();
            this.VerticalPosition.Increment = new decimal(new int[] {
            1,
            0,
            0,
            65536});
            this.VerticalPosition.LabelAreaWidthTemplate = "Horizontal";
            this.VerticalPosition.LabelText = "Vertical";
            this.VerticalPosition.Location = new System.Drawing.Point(25, 42);
            this.VerticalPosition.Maximum = new decimal(new int[] {
            65536,
            0,
            0,
            0});
            this.VerticalPosition.Minimum = new decimal(new int[] {
            65536,
            0,
            0,
            -2147483648});
            this.VerticalPosition.Name = "VerticalPosition";
            this.VerticalPosition.Size = new System.Drawing.Size(106, 24);
            this.VerticalPosition.TabIndex = 5;
            this.VerticalPosition.TextEditorWidth = 25;
            this.LayoutGroup.SetVerticallyDistributed(this.VerticalPosition, true);
            // 
            // HorizontalPositionDescription
            // 
            this.HorizontalPositionDescription.Id = Helper.GenerateGuid();
            this.HorizontalPositionDescription.Location = new System.Drawing.Point(132, 10);
            this.HorizontalPositionDescription.Name = "HorizontalPositionDescription";
            this.HorizontalPositionDescription.Size = new System.Drawing.Size(10, 24);
            this.HorizontalPositionDescription.TabIndex = 6;
            this.HorizontalPositionDescription.Text = "in";
            this.HorizontalPositionDescription.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            this.LayoutGroup.SetVerticallyDistributed(this.HorizontalPositionDescription, true);
            // 
            // HorizontalPositionDescription
            // 
            this.LayoutGroup.SetFlowBreak(this.VerticalPositionDescription, true);
            this.VerticalPositionDescription.Id = Helper.GenerateGuid();
            this.VerticalPositionDescription.Location = new System.Drawing.Point(132, 42);
            this.VerticalPositionDescription.Name = "HorizontalPositionDescription";
            this.VerticalPositionDescription.Size = new System.Drawing.Size(10, 24);
            this.VerticalPositionDescription.TabIndex = 7;
            this.VerticalPositionDescription.Text = "in";
            this.VerticalPositionDescription.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            this.LayoutGroup.SetVerticallyDistributed(this.VerticalPositionDescription, true);
            // 
            // Separator
            // 
            this.Separator.Id = Helper.GenerateGuid();
            this.Separator.Location = new System.Drawing.Point(145, 7);
            this.Separator.Name = "Separator";
            this.Separator.Size = new System.Drawing.Size(2, 60);
            this.Separator.TabIndex = 14;
            this.Separator.Text = "Separator";
            // 
            // Rotation
            // 
            this.Rotation.Id = Helper.GenerateGuid();
            this.Rotation.LabelText = "Rotation";
            this.Rotation.Location = new System.Drawing.Point(151, 10);
            this.Rotation.Maximum = new decimal(new int[] {
            360,
            0,
            0,
            0});
            this.Rotation.Minimum = new decimal(new int[] {
            360,
            0,
            0,
            -2147483648});
            this.Rotation.Name = "Rotation";
            this.Rotation.Size = new System.Drawing.Size(96, 24);
            this.Rotation.TabIndex = 9;
            this.Rotation.TextEditorWidth = 25;
            this.LayoutGroup.SetVerticallyDistributed(this.Rotation, true);
            // 
            // OpacityLevel
            // 
            this.LayoutGroup.SetFlowBreak(this.OpacityLevel, true);
            this.OpacityLevel.Id = Helper.GenerateGuid();
            this.OpacityLevel.LabelAreaWidthTemplate = "Rotation";
            this.OpacityLevel.LabelText = "Opacity";
            this.OpacityLevel.Location = new System.Drawing.Point(151, 42);
            this.OpacityLevel.Name = "OpacityLevel";
            this.OpacityLevel.Size = new System.Drawing.Size(96, 24);
            this.OpacityLevel.TabIndex = 11;
            this.OpacityLevel.TextEditorWidth = 25;
            this.OpacityLevel.Value = new decimal(new int[] {
            100,
            0,
            0,
            0});
            this.LayoutGroup.SetVerticallyDistributed(this.OpacityLevel, true);
            // 
            // RotationDescription
            // 
            this.RotationDescription.Id = Helper.GenerateGuid();
            this.RotationDescription.Location = new System.Drawing.Point(248, 10);
            this.RotationDescription.Name = "RotationDescription";
            this.RotationDescription.Size = new System.Drawing.Size(90, 24);
            this.RotationDescription.TabIndex = 12;
            this.RotationDescription.Text = "clockwise";
            this.RotationDescription.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            this.LayoutGroup.SetVerticallyDistributed(this.RotationDescription, true);
            // 
            // OpacityLevelDescription
            // 
            this.LayoutGroup.SetFlowBreak(this.OpacityLevelDescription, true);
            this.OpacityLevelDescription.Id = Helper.GenerateGuid();
            this.OpacityLevelDescription.Location = new System.Drawing.Point(248, 42);
            this.OpacityLevelDescription.Name = "OpacityLevelDescription";
            this.OpacityLevelDescription.Size = new System.Drawing.Size(10, 24);
            this.OpacityLevelDescription.TabIndex = 13;
            this.OpacityLevelDescription.Text = "%";
            this.OpacityLevelDescription.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            this.LayoutGroup.SetVerticallyDistributed(this.OpacityLevelDescription, true);
            // 
            // PreviewGroup
            // 
            this.PreviewGroup.Controls.Add(this.Preview);
            this.PreviewGroup.DialogLauncherButtonVisible = false;
            this.PreviewGroup.Id = Helper.GenerateGuid();
            this.PreviewGroup.Location = new System.Drawing.Point(566, 3);
            this.PreviewGroup.Name = "PreviewGroup";
            this.PreviewGroup.Size = new System.Drawing.Size(71, 94);
            this.PreviewGroup.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Preview16)});
            this.PreviewGroup.TabIndex = 3;
            this.PreviewGroup.Text = "Preview";
            // 
            // Preview
            // 
            this.Preview.Id = Helper.GenerateGuid();
            this.Preview.LargeImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Preview)});
            this.Preview.Location = new System.Drawing.Point(4, 2);
            this.Preview.Name = "WatermarkPreview";
            this.Preview.Size = new System.Drawing.Size(62, 72);
            this.Preview.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Preview16)});
            this.Preview.TabIndex = 0;
            this.Preview.Text = "Preview";

            ((System.ComponentModel.ISupportInitialize)(this.LayoutGroup)).EndInit();
            this.LayoutGroup.ResumeLayout(false);
            this.LayoutGroup.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.HorizontalPosition)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.VerticalPosition)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Rotation)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.OpacityLevel)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.PreviewGroup)).EndInit();
            this.PreviewGroup.ResumeLayout(false);
            this.PreviewGroup.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        #region Methods
        protected abstract void RenderPage(XGraphics gfx);

        protected override void InstallEventHandlers()
        {
            this.Preview.PressedChanged += new EventHandler(Preview_PressedChanged);
            this.HorizontalPosition.ValueChanged += new EventHandler(CustomLayout_Changed);
            this.VerticalPosition.ValueChanged += new EventHandler(CustomLayout_Changed);
            this.Rotation.ValueChanged += new EventHandler(CustomLayout_Changed);
            this.OpacityLevel.ValueChanged += new EventHandler(CustomLayout_Changed);
            this.LayoutGallery.SelectedItemChanged += new EventHandler<GallerySelectedItemChangedEventArgs>(
                                delegate(object sender, GallerySelectedItemChangedEventArgs e)
                                {
                                    UpdatePageOnlyControls();
                                    UpdatePreviewer();
                                });
            this.LayoutGallery.HoveredItemChanged += new EventHandler<GalleryHoveredItemChangedEventArgs>(Gallery_HoveredItemChanged);
        }

        protected void EnableLayoutParameters(bool enable)
        {
            this.HorizontalPosition.Enabled = enable;
            this.HorizontalPositionDescription.Enabled = enable;
            this.VerticalPosition.Enabled = enable;
            this.VerticalPositionDescription.Enabled = enable;
            this.Rotation.Enabled = enable;
            this.RotationDescription.Enabled = enable;
            this.OpacityLevel.Enabled = enable;
            this.OpacityLevelDescription.Enabled = enable;
        }

        private void CustomLayout_Changed(object sender, EventArgs e)
        {
            this.LayoutGallery.SetupCustomLayout(this.WatermarkPosition, this.WatermarkOpacity);

            UpdatePreviewer();
        }

        protected void Gallery_HoveredItemChanged(object sender, 
            GalleryHoveredItemChangedEventArgs e)
        {
            UpdatePreviewer();
        }

        private void Preview_PressedChanged(object sender, EventArgs e)
        {
            if (this.Preview.Pressed)
            {
                string operateItem = Global.Grid.OperateItem;
                PdfPageInformer pageInformer = new PdfPageInformer(operateItem);
                if (!pageInformer.IsValid)
                {
                    string errorMsg = Resources.UnableToOpenFile;
                    errorMsg.Replace("{file}", operateItem);
                    Global.ShowNotification(errorMsg);
                    return;
                }
                Global.MainWindow.Previewer.PageInformer = pageInformer;
                
                Global.MainWindow.Previewer.Show();
                Global.MainWindow.Previewer.BringToFront();
                Global.MainWindow.Previewer.RenderEvent = RenderPage;
                Global.MainWindow.UpdateRibbon();
            }
            else
            {
                Global.MainWindow.Previewer.Hide();
                Global.MainWindow.UpdateRibbon();
            }
        }

        protected void WatermarkChanged(object sender, EventArgs e)
        {
            UpdatePreviewer();
        }

        public override void UpdatePageOnlyControls()
        {
            if (!componentsInitialized)
            {
                return;
            }

            Helper.EnableControl(this.LayoutGroup, layoutGroupEnabled);
            Helper.EnableControl(this.LayoutGallery, layoutGroupEnabled);
            this.EnableLayoutParameters(layoutGroupEnabled &&
                                            this.LayoutGallery.IsCustomLayoutSelected);
            Helper.EnableControl(this.PreviewGroup, layoutGroupEnabled && 
                !string.IsNullOrEmpty( Global.Grid.OperateItem));

            Global.MainWindow.UpdateActionGroup();
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        protected void UpdatePreviewer()
        {
            if (this.Preview.Pressed && Global.MainWindow.Previewer.Visible)
            {
                Global.MainWindow.Previewer.UpdatePreviewer();
            }
        }

        protected override ActionItem GetIthActionItem(TataGrid grid, int i)
        {
            var item = new WatermarkItem();
            item.Source = (string)grid.Source.GetValueAt(i);
            item.From = (int)grid.From.GetValueAt(i);
            item.To = (int)grid.To.GetValueAt(i);


            return item;
        }

        public override void ImportSession(System.Xml.XmlElement sessionNode)
        {
            base.ImportSession(sessionNode);

            XmlElement layoutNode = (XmlElement) sessionNode.GetElementsByTagName(layoutTag)[0];
            TataLayoutKind layoutKind = (TataLayoutKind) Enum.Parse(typeof(TataLayoutKind),
                layoutNode.GetAttribute(layoutKindAttr), true);
            this.LayoutGallery.SelectedLayout = TataLayout.CreateLayout(layoutKind);

            if (layoutKind == TataLayoutKind.Custom)
            {
                //import other parameters like position/rotation/opacity
                float horizontalPosition = float.Parse(layoutNode.
                    GetAttribute(horizontalPositionAttr));
                float verticalPosition = float.Parse(layoutNode.
                    GetAttribute(verticalPositionAttr));
                int rotation = Int32.Parse(layoutNode.
                    GetAttribute(rotationAttr));
                int opacity = Int32.Parse(layoutNode.GetAttribute(opacityAttr));

                this.HorizontalPosition.Value = (decimal)horizontalPosition;
                this.VerticalPosition.Value = (decimal)verticalPosition;
                this.Rotation.Value = rotation;
                this.OpacityLevel.Value = opacity;
            }
        }

        public override void ExportSession(System.Xml.XmlElement sessionNode)
        {
            base.ExportSession(sessionNode);

            XmlElement layoutNode = sessionNode.OwnerDocument.CreateElement(layoutTag);
            layoutNode.SetAttribute(layoutKindAttr, this.WatermarkLayout.Kind.ToString());

            if (this.WatermarkLayout.Kind == TataLayoutKind.Custom)
            {
                layoutNode.SetAttribute(horizontalPositionAttr, 
                    this.HorizontalPosition.Value.ToString());
                layoutNode.SetAttribute(verticalPositionAttr,
                    this.VerticalPosition.Value.ToString());
                layoutNode.SetAttribute(rotationAttr,
                    this.Rotation.Value.ToString());
                layoutNode.SetAttribute(opacityAttr,
                    this.OpacityLevel.Value.ToString());
            }

            sessionNode.AppendChild(layoutNode);
        }

        #endregion

        #region Fields


        protected Elegant.Ui.RibbonGroup LayoutGroup;

        protected Elegant.Ui.NumericUpDown HorizontalPosition;
        protected Elegant.Ui.NumericUpDown VerticalPosition;
        protected Elegant.Ui.Label HorizontalPositionDescription;
        protected Elegant.Ui.Label VerticalPositionDescription;
        protected Elegant.Ui.NumericUpDown Rotation;
        protected Elegant.Ui.NumericUpDown OpacityLevel;
        protected Elegant.Ui.Label RotationDescription;
        protected Elegant.Ui.Label OpacityLevelDescription;
        protected Elegant.Ui.Separator Separator;

        protected Elegant.Ui.RibbonGroup PreviewGroup;
        protected Elegant.Ui.ToggleButton Preview;
        protected iPdf.LayoutGallery LayoutGallery;

        protected bool layoutGroupEnabled;
        private string layoutTag = "Layout";
        private string layoutKindAttr = "Kind";
        private string horizontalPositionAttr = "Horizontal";
        private string verticalPositionAttr = "Vertical";
        private string rotationAttr = "Rotation";
        private string opacityAttr = "Opacity";

        protected string markTag = "Mark";
        #endregion
    }
}
